//
//  VideoPlayerViewController.swift
//  GenericProjectForSwift
//
//  Created by 皮蛋菌 on 2023/5/14.
//  Copyright © 2023 漠然丶情到深处. All rights reserved.
//

import UIKit
import AVFoundation

class VideoPlayerViewController: LSBaseViewController {
    var videoURL: URL!
    var player: AVPlayer?
    var playerLayer: AVPlayerLayer?
    var isFullScreen: Bool = false
    var timer: Timer?
    var brightnessTimer: Timer?
    var volumeTimer: Timer?
    var playerSkinView: PlayerSkinView?
    var brightnessView: VolumeBrightnessView?
    var volumeView: VolumeBrightnessView?
    var screenLight: Float = 0.0
    var screenVolume: Float = 0.0

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = LSBlackColor
        // Do any additional setup after loading the view.
        createSubViews()
    }
    
    override func createSubViews() {
        guard let videoURL = self.videoURL else { return }
        let playerItem = AVPlayerItem(url: videoURL)
        let videoName = (videoURL.lastPathComponent as NSString).deletingPathExtension

        player = AVPlayer(playerItem: playerItem)
        playerLayer = AVPlayerLayer(player: self.player)
        playerLayer!.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
        self.view.layer.addSublayer(playerLayer!)

        playerSkinView = PlayerSkinView.init()
        self.view.addSubview(playerSkinView!)
        playerSkinView?.snp.makeConstraints { (make) in
            make.top.left.equalTo(self.view).offset(0)
            make.size.equalTo(CGSize(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height))
        }

        playerSkinView!.titleLabel!.text = videoName
        
        playerSkinView?.blackActionBlock = { [weak self] in
            AppDelegate.shareAppDelegate().launchScreen = false
            self!.dismiss(animated: true)
        }
        
        playerSkinView?.playActionBlock = { [weak self] (isPlayer) in
            if isPlayer {
                self!.player?.pause()
                self!.stopTimer()
            }else{
                self!.player?.play()
                self!.startTimer()
            }
        }
        
        playerSkinView?.progressChangeBlock = { [weak self] in
            guard let duration = self!.player?.currentItem?.duration else { return }
            let seconds = CMTimeGetSeconds(duration)
            let time = seconds * Float64(self!.playerSkinView!.progressSlider!.value)
            self!.player?.seek(to: CMTimeMakeWithSeconds(time, preferredTimescale: 1))
        }
        
        playerSkinView?.rateActionBlock = { [weak self] (rateButton) in
            let rate = self!.player?.rate
            if rate == 1.0 {
                self!.player?.rate = 1.5
                rateButton.setTitle("1.5", for: .normal)
            } else if rate == 1.5 {
                self!.player?.rate = 2.0
                rateButton.setTitle("2.0", for: .normal)
            } else {
                self!.player?.rate = 1.0
                rateButton.setTitle("1.0", for: .normal)
            }
        }
        
        playerSkinView!.fullScreenActionBlock = { [weak self] (isFull) in
            self!.isFullScreen = isFull
            self!.switchOrientation(withLaunchScreen: isFull)
        }
        
        // 创建亮度调节的 UI
        brightnessView = VolumeBrightnessView.init()
        brightnessView?.alpha = 0
        brightnessView?.layer.masksToBounds = true
        brightnessView?.layer.cornerRadius = LSSYRealValue(value1: 2, value2: 4)
        self.view.addSubview(brightnessView!)
        brightnessView?.snp.makeConstraints({ make in
            make.centerX.equalTo(self.view.snp.centerX);
            make.centerY.equalTo(self.view.snp.centerY);
            make.size.equalTo(CGSize(width: LSSYRealValue(value1: 150, value2: 300), height: LSSYRealValue(value1: 20, value2: 40)))
        })
        // 创建音量调节的 UI
        volumeView = VolumeBrightnessView.init()
        volumeView?.alpha = 0
        volumeView?.layer.masksToBounds = true
        volumeView?.layer.cornerRadius = LSSYRealValue(value1: 2, value2: 4)
        self.view.addSubview(volumeView!)
        volumeView?.snp.makeConstraints({ make in
            make.centerX.equalTo(self.view.snp.centerX);
            make.centerY.equalTo(self.view.snp.centerY);
            make.size.equalTo(CGSize(width: LSSYRealValue(value1: 150, value2: 300), height: LSSYRealValue(value1: 20, value2: 40)))
        })
        
        updateBrightnessUI()
        updateVolumeUI()

        player!.play()
        
        self.playerSkinView!.durationLabel!.text = formatTime(CMTimeGetSeconds(playerItem.duration))
        // Add tap gesture recognizer for showing/hiding controls
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(_:)))
        self.view.addGestureRecognizer(tapGestureRecognizer)

        let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
        self.view.addGestureRecognizer(panGestureRecognizer)

        self.player!.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1, preferredTimescale: 10), queue: DispatchQueue.main) { [weak self] time in
            self?.updateUI()
        }

        //监听播放状态，结束时，重置进度条位置，播放状态，按钮状态，播放进度
        NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player?.currentItem, queue: OperationQueue.main) { [weak self] note in
            guard let self = self else { return }
            // 播放结束，重置状态和进度条
            self.player!.seek(to: CMTime.zero)
            self.player!.pause()
            self.playerSkinView!.progressSlider!.setValue(0.0, animated: true)
            self.playerSkinView!.playButton?.isSelected = true
        }
    }
    
    // 皮肤点击方法
    @objc func handleTapGesture(_ gestureRecognizer: UITapGestureRecognizer) {
        if gestureRecognizer.state == .recognized {
            if playerSkinView!.alpha == 1.0 {
                hideControls()
            } else {
                showControls()
            }
        }
    }

    func startTimer() {
        stopTimer()
        timer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(hideControls), userInfo: nil, repeats: false)
    }

    func stopTimer() {
        timer?.invalidate()
        timer = nil
    }

    func showControls() {
        UIView.animate(withDuration: 0.25) {
            self.playerSkinView!.alpha = 1.0
        } completion: { finished in
            self.startTimer()
        }
    }

    @objc func hideControls() {
        UIView.animate(withDuration: 0.25) {
            self.playerSkinView!.alpha = 0.0
        } completion: { finished in
            self.stopTimer()
        }
    }
    
    // 更新播放进度与播放时间
    func updateUI() {
        let durationSeconds = CMTimeGetSeconds(player?.currentItem?.duration ?? CMTime.zero)
        let timeSeconds = CMTimeGetSeconds(player?.currentItem?.currentTime() ?? CMTime.zero)

        guard let duration = player?.currentItem?.duration else { return }
        let durationInSeconds = CGFloat(duration.value) / CGFloat(duration.timescale)
        // 更新播放时间
        playerSkinView!.timeLabel?.text = timeStringFromSeconds(CMTimeGetSeconds(player!.currentTime()))
        playerSkinView!.durationLabel!.text = timeStringFromSeconds(durationInSeconds)
        playerSkinView!.progressSlider!.value = Float(timeSeconds / durationSeconds)
    }

    func timeStringFromSeconds(_ seconds: CGFloat) -> String {
        if seconds > 0.0 {
            let formatter = DateComponentsFormatter()
            formatter.zeroFormattingBehavior = .pad
            formatter.allowedUnits = [.minute, .second]
            return formatter.string(from: TimeInterval(seconds)) ?? "00:00"
        }else{
            return "00:00"
        }
    }

    func formatTime(_ time: Double) -> String {
        if time.isFinite {
            let minutes = Int(time / 60)
            let seconds = Int(time) % 60
            return String(format: "%02d:%02d", minutes, seconds)
        } else {
            return "00:00"
        }
    }

    deinit {
        timer?.invalidate()
        brightnessTimer?.invalidate()
        volumeTimer?.invalidate()
        NotificationCenter.default.removeObserver(self)
    }

    /// 切换设备方向
    func switchOrientation(withLaunchScreen isLaunchScreen: Bool) {
        if isLaunchScreen {
            // 全屏操作
            AppDelegate.shareAppDelegate().launchScreen = true
        } else {
            // 退出全屏操作
            AppDelegate.shareAppDelegate().launchScreen = false
        }
        if #available(iOS 16.0, *) {
            setNeedsUpdateOfSupportedInterfaceOrientations()
            let array = UIApplication.shared.connectedScenes
            if let scene = array.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
                // 屏幕方向
                let orientation: UIInterfaceOrientationMask = isLaunchScreen ? .landscapeRight : .portrait
                let geometryPreferencesIOS = UIWindowScene.GeometryPreferences.iOS(interfaceOrientations: orientation)
                
                // 开始切换
                scene.requestGeometryUpdate(geometryPreferencesIOS)
            }
        } else {
            swichToNewOrientation(isLaunchScreen ? .landscapeRight : .portrait)
        }
    }

    /// iOS16 之前进行横竖屏切换方式
    /// - Parameter interfaceOrientation: 需要切换的方向
    func swichToNewOrientation(_ interfaceOrientation: UIInterfaceOrientation) {
        let orientationTarget = NSNumber(integerLiteral: interfaceOrientation.rawValue)
        UIDevice.current.setValue(orientationTarget, forKey: "orientation")
    }

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        
        var isLaunchScreen = false
        if #available(iOS 16.0, *) {
            let array = UIApplication.shared.connectedScenes
            if let scene = array.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
                isLaunchScreen = scene.interfaceOrientation == .landscapeRight
            }
        } else {
            isLaunchScreen = UIDevice.current.orientation == .landscapeLeft
        }
        
        updateView(withLaunchScreen: isLaunchScreen, size: size)
    }

    func updateView(withLaunchScreen isLaunchScreen: Bool, size: CGSize) {
        playerLayer!.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
        playerSkinView?.snp.updateConstraints({ make in
            make.top.equalTo(self.view).offset(0)
            make.left.equalTo(self.view).offset(0)
            make.size.equalTo(CGSize(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height))
        })
    }

    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        if AppDelegate.shareAppDelegate().launchScreen {
            return .landscapeRight
        }
        return .portrait
    }

    func updateVolumeUI() {
        let volume = getCurrentVolume()
        volumeView!.setProgress(Float(volume))
    }
    
    func updateBrightnessUI() {
        let brightness = UIScreen.main.brightness
        brightnessView!.setProgress(Float(brightness))
    }
    
    func getCurrentVolume() -> CGFloat {
        let audioSession = AVAudioSession.sharedInstance()
        let currentVolume = audioSession.outputVolume
        return CGFloat(currentVolume)
    }
    
    @objc func handlePanGesture(_ gestureRecognizer: UIPanGestureRecognizer) {
        let translation = gestureRecognizer.translation(in: self.view)
        let location = gestureRecognizer.location(in: self.view)
        let screenWidth = UIScreen.main.bounds.width
        let screenHeight = UIScreen.main.bounds.height
        let deltaBrightness: CGFloat = 0.5
        let deltaVolume: CGFloat = 0.2
        let delta = -translation.y / screenHeight
        let progressDelta = translation.x / gestureRecognizer.view!.bounds.width
        let verticalDelta = translation.y / gestureRecognizer.view!.bounds.height
        
        if gestureRecognizer.state == .changed {
            if abs(verticalDelta) < abs(progressDelta) {
                //横向滑动调节播放进度，有问题
            }else if location.x < screenWidth / 2 {
                //调节亮度
                screenLight = Float(UIScreen.main.brightness)
                screenLight += Float(deltaBrightness * delta)
                screenLight = max(0.0, min(1.0, screenLight))
                UIScreen.main.brightness = CGFloat(screenLight)
                adjustBrightnessByDelta(screenLight)
                
                if brightnessView!.alpha == 1.0 {
                    hideBrightnessControls()
                } else {
                    showBrightnessControls()
                }
                
                if volumeView!.alpha == 1.0 {
                    volumeView!.alpha = 0
                }
            } else {
                //调节音量
                screenVolume = player!.volume
                screenVolume += Float(deltaVolume * delta)
                screenVolume = max(0.0, min(1.0, screenVolume))
                player!.volume = screenVolume
                adjustVolumeByDelta(screenVolume)
                
                if volumeView!.alpha == 1.0 {
                    hideVolumeControls()
                } else {
                    showVolumeControls()
                }
                
                if brightnessView!.alpha == 1.0 {
                    brightnessView!.alpha = 0
                }
            }
        } else if gestureRecognizer.state == .ended {
            // 处理结束状态
        }
    }
    
    func adjustBrightnessByDelta(_ delta: Float) {
        brightnessView!.setProgress(delta)
    }
    
    func adjustVolumeByDelta(_ delta: Float) {
        volumeView!.setProgress(delta)
    }
    
    func showBrightnessControls() {
        UIView.animate(withDuration: 0.25) {
            self.brightnessView!.alpha = 1.0
        } completion: { (_) in
            self.startBrightnessTimer()
        }
    }
    
    @objc func hideBrightnessControls() {
        UIView.animate(withDuration: 0.25) {
            self.brightnessView!.alpha = 0.0
        } completion: { (_) in
            self.stopBrightnessTimer()
        }
    }
    
    func startBrightnessTimer() {
        stopBrightnessTimer()
        brightnessTimer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(hideBrightnessControls), userInfo: nil, repeats: false)
    }
    
    func stopBrightnessTimer() {
        brightnessTimer?.invalidate()
        brightnessTimer = nil
    }
    
    func showVolumeControls() {
        UIView.animate(withDuration: 0.25) {
            self.volumeView!.alpha = 1.0
        } completion: { (_) in
            self.startVolumeTimer()
        }
    }
    
    @objc func hideVolumeControls() {
        UIView.animate(withDuration: 0.25) {
            self.volumeView!.alpha = 0.0
        } completion: { (_) in
            self.stopVolumeTimer()
        }
    }
    
    func startVolumeTimer() {
        stopVolumeTimer()
        volumeTimer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(hideVolumeControls), userInfo: nil, repeats: false)
    }
    
    func stopVolumeTimer() {
        volumeTimer?.invalidate()
        volumeTimer = nil
    }
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}
